## code to run muni-level MSMs and other models ##

msm_muni <- function(dv1, dv2, dvp, indata1, indata2, num){
  
  print(paste0("MUNI ", num))
  
  af.muni.reg <- remove_missing_from_mids(indata1, c(dv1, dv2))
  
  af.muni.t1t2 <- complete(af.muni.reg, "long", include = T)
  nrows <- nrow(af.muni.t1t2)/length(unique(af.muni.t1t2$.imp))
  
  print("COMPLETE OBS")
  print(nrow(af.muni.t1t2))
  
  vars.2022 <- paste(c("pop_total_2022","pop_density_2022",
                       "per_18t34_2022","per_35t64_2022",
                       "per_65over_2022","entropy_er_2022",
                       "per_child_2022", "per_nomove_2022",
                       "hownrt_2022", "per_immigrant_2022",
                       "median_yr_str_2022","median_hhld_inc_2022",
                       "hhld_pov_rt_2022","unem_rt_2022",
                       "gini_2022"
  ), collapse = "+")
  
  vars.2009 <- paste(c("pop_total_2009","pop_density_2009",
                       "per_18t34_2009","per_35t64_2009",
                       "per_65over_2009", "entropy_er_2009",
                       "per_child_2009", "per_nomove_2009",
                       "hownrt_2009", "per_immigrant_2009",
                       "median_yr_str_2009","median_hhld_inc_2009",
                       "hhld_pov_rt_2009","unem_rt_2009",
                       "gini_2009"
  ), collapse = "+")
  
  fe.vars <- paste(c("pop_total","pop_density",
                     "per_18t34","per_35t64",
                     "per_65over", "entropy_er",
                     "per_child", "per_nomove",
                     "hownrt","per_immigrant",
                     "median_yr_str","median_hhld_inc",
                     "hhld_pov_rt","unem_rt",
                     "gini","GEOID","tp"
  ), collapse = "+")
  
  ## regression formulas ##
  
  form1 <- paste0("treat_2022 ~ ",
                  dv1, " + treat_2006 +",
                  vars.2022)
  
  form2 <- paste0("treat_2006 ~ ", 
                  vars.2009)
  
  form3 <- paste0(dv2," ~",
                  "thist")
  
  form4 <- paste0(dv2," ~",
                  "zri_2022_fin_st +",
                  "zri_2006_fin_st +",
                  dv1," +",
                  vars.2022," +",
                  vars.2009)
  
  form5 <- paste0(dvp," ~",
                  "zri_fin"," +",
                  fe.vars)
  
  muni.2022 <- with(af.muni.reg,
                   glm(as.formula(form1),
                       binomial(link = 'logit')))
  
  summary(pool(muni.2022))
  
  ## credit for how to do this: ##
  ## https://github.com/amices/mice/issues/82 ##
  
  ppout.2022 <- lapply(getfit(muni.2022), predict, type = "response", se.fit = TRUE)
  pps.2022 <- sapply(ppout.2022, `[[`, "fit")

  print("PPS")
  print(length(pps.2022))
  
  ## check weights ##
  summary(pps.2022)
  
  ## convert the matrix of pps to a vector ##
  pps.2022.temp <- c()
  
  for(j in 1:ncol(pps.2022)) {
    pps.2022.temp <- c(pps.2022.temp, pps.2022[,j ])
  }
  
  prop.table(table(af.muni.t1t2$treat_2022))
  
  ## numerator for stabilized weights ##
  
  muni.2022.nm <- with(af.muni.reg,
                      glm(treat_2022 ~ 
                            treat_2006,
                          binomial(link = 'logit')))
  
  summary(pool(muni.2022.nm))
  
  ppout.2022.num <- lapply(getfit(muni.2022.nm), predict, type = "response", se.fit = TRUE)
  pps.2022.num <- sapply(ppout.2022.num, `[[`, "fit")
  
  ## check probabilities ##
  summary(pps.2022.num)
  
  pps.2022.num.rf <- c()
  for(j in 1:ncol(pps.2022.num)) {
    pps.2022.num.rf <- c(pps.2022.num.rf, pps.2022.num[,j ])
  }
  
  summary(pps.2022.num.rf)
  
  muni.2006 <- with(af.muni.reg,
                   glm(as.formula(form2),
                       binomial(link = 'logit')))
  
  summary(pool(muni.2006))
  
  ppout.2006 <- lapply(getfit(muni.2006), predict, type = "response", se.fit = TRUE)
  pps.2006 <- sapply(ppout.2006, `[[`, "fit")

  summary(pps.2006)
  
  ## convert the matrix of pps to a vector ##
  pps.2006.temp <- c()
  
  for(j in 1:ncol(pps.2006)) {
    pps.2006.temp <- c(pps.2006.temp, pps.2006[,j ])
  }
  
  num06.calc <- af.muni.t1t2 %>%
    filter(.imp != 0) %>%
    group_by(.imp) %>%
    summarize(num = mean(treat_2006,na.rm=T)) %>%
    slice(rep(1:n(), each = nrows))
  
  num06 <- num06.calc$num
  
  print("LENGTHS - REG")
  print(length(pps.2006.temp))
  print(length(pps.2022.temp))
  
  ## concatenate NAs for .imp = 0 ##
  pps.2006.num.fin <- c(rep(NA,nrows),num06)
  pps.2022.fin <- c(rep(NA,nrows),pps.2022.temp)
  pps.2022.num.fin <- c(rep(NA,nrows),pps.2022.num.rf)
  pps.2006.fin <- c(rep(NA,nrows),pps.2006.temp)

  ## attach the pps and numerators and create weights ##
  
  af.muni.wts <- complete(af.muni.reg, 'long', include = TRUE) %>%
    mutate(thist = treat_2006 + treat_2022,
           num_t_2006 = pps.2006.num.fin,
           pps_2006 = pps.2006.fin,
           num_t_2022 = pps.2022.num.fin,
           pps_2022 = pps.2022.fin,
           num_2006 = ifelse(treat_2006 == 1, num_t_2006, 1-num_t_2006),
           den_2006 = ifelse(treat_2006 == 1, pps_2006, 1-pps_2006),
           num_2022 = ifelse(treat_2022 == 1, num_t_2022, 1-num_t_2022),
           den_2022 = ifelse(treat_2022 == 1, pps_2022, 1-pps_2022),
           swt_2006 = num_2006/den_2006,
           swt_2022 = num_2022/den_2022,
           swt_fin = swt_2006 * swt_2022)
  
  ## truncate the weights ##
  
  wts.cb.p5 <- quantile(af.muni.wts$swt_fin, 0.05, na.rm=T)
  wts.cb.p95 <- quantile(af.muni.wts$swt_fin,0.95, na.rm=T)
  
  af.muni.wts$swt_fin[af.muni.wts$swt_fin > wts.cb.p95] <- wts.cb.p95
  af.muni.wts$swt_fin[af.muni.wts$swt_fin < wts.cb.p5] <- wts.cb.p5
  summary(af.muni.wts$swt_fin)
  sd(af.muni.wts$swt_fin, na.rm=T)
  
  summary(af.muni.wts$swt_fin)
  summary(af.muni.wts$swt_fin[af.muni.wts$.imp == 0])
  summary(af.muni.wts$swt_fin[af.muni.wts$.imp != 0])
  
  ## assign the weights for export ##
  wts.fin <- af.muni.wts$swt_fin
  
  af.muni.mids.fin <- as.mids(af.muni.wts)
  
  ## msm ##
  
  muni.msm <- with(af.muni.mids.fin,
                  lm(as.formula(form3),
                     weights=swt_fin))
  
  ## unadjusted ## 
  
  muni.noadj <- with(af.muni.mids.fin,
                    lm(as.formula(form3)))
  
  ## adl ## 
  
  muni.adl <- with(af.muni.mids.fin,
                  lm(as.formula(form4)))
  
  ## fixed effects ## 
  
  muni.fe <- with(indata2,
                 lm(as.formula(form5)))
  
  out.msm <- summary(pool(muni.msm))
  out.noadj <- summary(pool(muni.noadj))
  out.adl <- summary(pool(muni.adl))
  out.fe <- summary(pool(muni.fe))
  
  ## assess balance ##
  
  test <- complete(af.muni.mids.fin, "long", include = T)
  
  bal.t2.vars <- c("pop_total_2022","pop_density_2022",
                   "per_18t34_2022","per_35t64_2022",
                   "per_65over_2022", "entropy_er_2022",
                   "per_child_2022", "per_nomove_2022",
                   "hownrt_2022", "per_immigrant_2022",
                   "median_yr_str_2022","median_hhld_inc_2022",
                   "hhld_pov_rt_2022","unem_rt_2022","gini_2022")
  
  bal.t1.vars <- c("pop_total_2009","pop_density_2009",
                   "per_18t34_2009","per_35t64_2009",
                   "per_65over_2009", "entropy_er_2009",
                   "per_child_2009", "per_nomove_2009",
                   "hownrt_2009", "per_immigrant_2009",
                   "median_yr_str_2009","median_hhld_inc_2009",
                   "hhld_pov_rt_2009","unem_rt_2009","gini_2009")
  
  bal.t2 <- function(var){
    
    unwt2 <- with(af.muni.mids.fin,
                  lm(as.formula(paste0(var,
                                       " ~ treat_2022 + treat_2006"))))
    
    out2a <- summary(pool(unwt2))
    
    
    wt2 <- with(af.muni.mids.fin,
                lm(as.formula(paste0(var,
                                     " ~ treat_2022 + treat_2006")),
                   weights=swt_fin))
    
    out2b <- summary(pool(wt2))
    
    outres <- list(out2a,out2b)
    
    return(outres)
    
  }
  
  t2.bal <- lapply(bal.t2.vars, bal.t2)  
  
  bal.t1 <- function(var){
    
    unwt1 <- with(af.muni.mids.fin,
                  lm(as.formula(paste0(var,
                                       " ~ treat_2006"))))
    
    out1a <- summary(pool(unwt1))
    
    
    wt1 <- with(af.muni.mids.fin,
                lm(as.formula(paste0(var,
                                     " ~ treat_2006")),
                   weights=swt_fin))
    
    out1b <- summary(pool(wt1))
    
    outres <- list(out1a,out1b)
    
    return(outres)
    
  }
  
  t1.bal <- lapply(bal.t1.vars, bal.t1)  
  
  ## capture all output ## 
  
  res <- list(out.msm,
              wts.fin,
              out.noadj,
              out.adl,
              out.fe,
              t2.bal,
              t1.bal)
  
  return(res)
  
}

